
package gipf.trunk;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;

import javax.swing.JComponent;

public class BoardComponent extends JComponent {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public int frameWidth;
	public int frameHeight;
	static int tolerance = 50; // pixels around certain point

	private int z;
	private int s;

	public int getS() {
		return s;
	}

	public void setS(int s) {
		this.s = s;
	}

	public int getWidth() {
		return BoardView.width;

	}

	public int getHeight() {
		return BoardView.height;
	}

	@Override
	public void paintComponent(Graphics g) {
		// Set the length of the sides

		// Choose a nice colour :)
		Graphics2D g2 = (Graphics2D) g;

		// divide the screen in segments of variable size
		int horizontalSegment = ((getWidth()) / 9);
		int verticalSegment = ((getHeight()) / 9);

		Point originPoint = new Point((getWidth() / 2), getHeight() / 2
				- verticalSegment / 2);
		// superPointList.add(originPoint);

		// column and row guides are coordinates (from origin superPoint@screen
		// center) to multiply
		// times respective segments
		int[] columnGuides = new int[] { -4, -3, -2, -1, 0, 1, 2, 3, 4 };

		for (int i = 0; i < columnGuides.length; i++) {
			int deltaX = horizontalSegment * columnGuides[i];

			// only even rows keep same level: A, C, D, E, G, I
			// odd rows are half a verticalsegment shifted
			if ((i % 2) == 0) {
				if ((i == 0) || (i == 8)) {
					int[] rowGuideAI = new int[] { -2, -1, 0, 1, 2 };
					int[] indexA = new int[] { 0, 1, 2, 3, 4 };
					int[] indexI = new int[] { 56, 57, 58, 59, 60 };

					for (int j = 0; j < rowGuideAI.length; j++) {
						int deltaY = verticalSegment * rowGuideAI[j];

						if (i == 0)
							staticBoard.getPosition(indexA[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
							
						else
							staticBoard.getPosition(indexI[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
					}
				}

				if ((i == 2) || (i == 6)) {
					int[] rowGuideCG = new int[] { -3, -2, -1, 0, 1, 2, 3 };
					int[] indexC = new int[] { 11, 12, 13, 14, 15, 16, 17 };
					int[] indexG = new int[] { 43, 44, 45, 46, 47, 48, 49 };

					for (int j = 0; j < rowGuideCG.length; j++) {
						int deltaY = verticalSegment * rowGuideCG[j];
						if (i == 2)
							staticBoard.getPosition(indexC[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
							
						else
							staticBoard.getPosition(indexG[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
					}
				}

				if (i == 4) {
					int[] rowGuideE = new int[] { -4, -3, -2, -1, 0, 1, 2, 3, 4 };
					int[] indexE = new int[] { 26, 27, 28, 29, 30, 31, 32, 33, 34 };

					for (int j = 0; j < rowGuideE.length; j++) {
						int deltaY = verticalSegment * rowGuideE[j];
						staticBoard.getPosition(indexE[j]).setGUIcoordinate(originPoint.x + deltaX,
								originPoint.y - deltaY);

					}
				}

			} else {
				if ((i == 1) || (i == 7)) {
					int[] rowGuideBH = new int[] { -5, -3, -1, 1, 3, 5 };
					int[] indexB = new int[] { 5, 6, 7, 8, 9, 10 };
					int[] indexH = new int[] { 50, 51, 52, 53, 54, 55 };

					for (int j = 0; j < rowGuideBH.length; j++) {
						int deltaY = (verticalSegment / 2) * rowGuideBH[j];
						if (i == 1)
							staticBoard.getPosition(indexB[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
							
						else
							staticBoard.getPosition(indexH[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
					}
				}

				if ((i == 3) || (i == 5)) {
					int[] rowGuideDF = new int[] { -7, -5, -3, -1, 1, 3, 5, 7 };
					int[] indexD = new int[] { 18, 19, 20, 21, 22, 23, 24, 25 };
					int[] indexF = new int[] { 35, 36, 37, 38, 39, 40, 41, 42 };

					for (int j = 0; j < rowGuideDF.length; j++) {
						int deltaY = (verticalSegment / 2) * rowGuideDF[j];
						if (i == 3)
							staticBoard.getPosition(indexD[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
							
						else
							staticBoard.getPosition(indexF[j]).setGUIcoordinate(originPoint.x + deltaX,
									originPoint.y - deltaY);
					}
				}

			}

		}

		int npoints = 6;

		g2.setColor(Color.YELLOW);

		int[] xpoints = new int[] { staticBoard.getPosition(6).getGUIcoordinate()[0] + 10,
				staticBoard.getPosition(9).getGUIcoordinate()[0] + 10, staticBoard.getPosition(33).getGUIcoordinate()[0] + 10,
				staticBoard.getPosition(54).getGUIcoordinate()[0] + 10, staticBoard.getPosition(51).getGUIcoordinate()[0]+ 10,
				staticBoard.getPosition(27).getGUIcoordinate()[0] + 10 };
		int[] ypoints = new int[] { staticBoard.getPosition(6).getGUIcoordinate()[1] + 10,
				staticBoard.getPosition(9).getGUIcoordinate()[1] + 10, staticBoard.getPosition(33).getGUIcoordinate()[1] + 10,
				staticBoard.getPosition(54).getGUIcoordinate()[1] + 10, staticBoard.getPosition(51).getGUIcoordinate()[1] + 10,
				staticBoard.getPosition(27).getGUIcoordinate()[1] + 10 };

		g2.fillPolygon(xpoints, ypoints, npoints);

		g2.setColor(Color.BLACK);
		int[] from = new int[] { 5, 11, 18, 26, 35, 43, 50 };
		int[] to = new int[] { 10, 17, 25, 34, 42, 49, 55 };

		for (int i = 0; i < 7; i++) {
			int[] poinnt = staticBoard.getPosition(from[i]).getGUIcoordinate();
			int[] poiint = staticBoard.getPosition(to[i]).getGUIcoordinate();
			g2.drawLine(poinnt[0] + 10, poinnt[1] + 10, poiint[0] + 10,
					poiint[1] + 10);
		}

		from = new int[] { 35, 43, 50, 56, 57, 58, 59 };
		to = new int[] { 1, 2, 3, 4, 10, 17, 25 };

		for (int i = 0; i < 7; i++) {
			int[] poinnt = staticBoard.getPosition(from[i]).getGUIcoordinate();
			int[] poiint = staticBoard.getPosition(to[i]).getGUIcoordinate();
			g2.drawLine(poinnt[0] + 10, poinnt[1] + 10, poiint[0] + 10,
					poiint[1] + 10);

		}

		from = new int[] { 3, 2, 1, 0, 5, 11, 18 };
		to = new int[] { 42, 49, 55, 60, 59, 58, 57 };

		for (int i = 0; i < 7; i++) {
			int[] poinnt = staticBoard.getPosition(from[i]).getGUIcoordinate();
			int[] poiint = staticBoard.getPosition(to[i]).getGUIcoordinate();
			g2.drawLine(poinnt[0] + 10, poinnt[1] + 10, poiint[0] + 10,
					poiint[1] + 10);

		}

		g2.setColor(Color.BLUE);
		for (position printPoint : staticBoard.getPositionList()) {
			g2.fillOval(printPoint.getGUIcoordinate()[0], printPoint.getGUIcoordinate()[1], 20, 20);

		}

		// Draw some circles & scores :)
		int Xscore = 20;
		int Yscore1 = 10;
		int Yscore2 = 35;

		g2.setColor(Color.red);
		for (int j = 0; j < GameEngine.piecesAvailable[1]; j++) {
			g2.drawRect(Xscore + (j * 15), Yscore1, 10, 20);
			g2.fillRect(Xscore + (j * 15), Yscore1, 10, 20);
		}
		g2.setColor(Color.green);
		for (int j = 0; j < GameEngine.piecesAvailable[0]; j++) {
			g2.drawRect(Xscore + (j * 15), Yscore2, 10, 20);
			g2.fillRect(Xscore + (j * 15), Yscore2, 10, 20);

		}
		
		ArrayList<int[]> piecesPlaced = new ArrayList<int[]>();
		try {
			piecesPlaced = extractString(GameEngine.boardState.toString());
		} catch (Exception e) {
		}

		System.out.println(piecesPlaced.size() + " painted");
		if (piecesPlaced.size() > 0) {
			for (int[] pieceIndex : piecesPlaced) {
				int[] piecePoint = staticBoard.getPosition(pieceIndex[0]).getGUIcoordinate();
				switch (pieceIndex[1]) {
				case 0:
					g2.setColor(Color.magenta);
					break;
				case 1:
					g2.setColor(Color.green);
					break;

				case 2:
					g2.setColor(Color.red);
					break;
				default:
					g2.setColor(Color.white);
					break;
				}

				g2.fillOval(piecePoint[0], piecePoint[1], 25, 25);
				g2.setColor(Color.black);
				g2.drawOval(piecePoint[0] + 5, piecePoint[1] + 5, 15, 15);
				g2.drawOval(piecePoint[0], piecePoint[1], 25, 25);
			}
		}

	}

	private ArrayList<int[]> extractString(String boardState) {
		ArrayList<int[]> toBeReturned = new ArrayList<int[]>();
		
		String[] lines = boardState.split("\n");
		for (int i = 0; i < lines.length; i++){
			String[] output = lines[i].split(" ");
			int[] result = new int[2];
			result[0] = Integer.valueOf(output[0]);
			result[1] = Integer.valueOf(output[1]);

			toBeReturned.add(result);
		}
		
		return toBeReturned;
	}

	public int getZ() {
		return z;
	}

	public void setZ(int z) {
		this.z = z;
	}

}
